#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum OptionValue {
    NotSet = 0,
    On = 1, // Using on will prevent this value from changing in Microsoft Defender GUI
    Off = 2,
    Error = 4,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(dead_code)]
#[repr(u32)]
pub enum ProcessMitigationPolicy {
    ProcessDEPPolicy,
    ProcessASLRPolicy,
    ProcessDynamicCodePolicy,
    ProcessStrictHandleCheckPolicy,
    ProcessSystemCallDisablePolicy,
    ProcessMitigationOptionsMask,
    ProcessExtensionPointDisablePolicy,
    ProcessControlFlowGuardPolicy,
    ProcessSignaturePolicy,
    ProcessFontDisablePolicy,
    ProcessImageLoadPolicy,
    ProcessSystemCallFilterPolicy,
    ProcessPayloadRestrictionPolicy,
    ProcessChildProcessPolicy,
    ProcessSideChannelIsolationPolicy,
    ProcessUserShadowStackPolicy,
    ProcessRedirectionTrustPolicy,
    ProcessUserPointerAuthPolicy,
    ProcessSEHOPPolicy,
    MaxProcessMitigationPolicy,
}

#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum ProcessMitigationFlags {
    FlagNone = 0,
    FlagReset = 1,
    FlagRemove = 2,
    FlagOSDefault = 4,
    FlagAudit = 8,
}

// All of the valid mitigation options that can be used for enabling or disabling.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum MitigationOptions {
    DEP = 0,
    EmulateAtlThunks = 1,
    ForceRelocateImages = 2,
    RequireInfo = 3,
    BottomUp = 4,
    HighEntropy = 5,
    StrictHandle = 6,
    DisableWin32kSystemCalls = 7,
    AuditSystemCall = 8,
    DisableExtensionPoints = 9,
    DisableFsctlSystemCalls = 10,
    AuditFsctlSystemCall = 11,
    BlockDynamicCode = 12,
    AllowThreadsToOptOut = 13,
    AuditDynamicCode = 14,
    CFG = 15,
    SuppressExports = 16,
    StrictCFG = 17,
    MicrosoftSignedOnly = 18,
    AllowStoreSignedBinaries = 19,
    AuditMicrosoftSigned = 20,
    AuditStoreSigned = 21,
    EnforceModuleDependencySigning = 22,
    DisableNonSystemFonts = 23,
    AuditFont = 24,
    BlockRemoteImageLoads = 25,
    BlockLowLabelImageLoads = 26,
    PreferSystem32 = 27,
    AuditRemoteImageLoads = 28,
    AuditLowLabelImageLoads = 29,
    AuditPreferSystem32 = 30,
    EnableExportAddressFilter = 31,
    AuditEnableExportAddressFilter = 32,
    EnableExportAddressFilterPlus = 33,
    AuditEnableExportAddressFilterPlus = 34,
    EnableImportAddressFilter = 35,
    AuditEnableImportAddressFilter = 36,
    EnableRopStackPivot = 37,
    AuditEnableRopStackPivot = 38,
    EnableRopCallerCheck = 39,
    AuditEnableRopCallerCheck = 40,
    EnableRopSimExec = 41,
    AuditEnableRopSimExec = 42,
    SEHOP = 43,
    AuditSEHOP = 44,
    SEHOPTelemetry = 45,
    TerminateOnError = 46,
    DisallowChildProcessCreation = 47,
    AuditChildProcess = 48,
    UserShadowStack = 49,
    UserShadowStackStrictMode = 50,
    AuditUserShadowStack = 51,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PolicyName {
    DEP,
    ASLR,
    StrictHandle,
    SystemCalls,
    ExtensionPoints,
    DynamicCode,
    ControlFlowGuard,
    SignedBinaries,
    Fonts,
    ImageLoad,
    Payload,
    ChildProcess,
    UserShadowStack,
    SEHOP,
    Heap,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ForceName {
    DEP,
    FontDisable,
    ExtensionPoint,
    Heap,
    BlockRemoteImageLoads,
    BlockLowLabel,
    PreferSystem32,
    EnableExportAddressFilter,
    EnableExportAddressFilterPlus,
    EnableImportAddressFilter,
    EnableRopStackPivot,
    EnableRopCallerCheck,
    EnableRopSimExec,
    ForceRelocateImages,
    BottomUp,
    HighEntropy,
    CFG,
    StrictCFG,
    ChildProcess,
    DynamicCode,
    StrictHandle,
    SystemCall,
    DisableFsctlSystem,
    UserShadowStack,
    SEHOP,
    MicrosoftSignedOnly,
    EnforceModuleDependencySigning,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PolicyOptionName {
    Enable,
    EmulateAtlThunks,
    ForceRelocateImages,
    RequireInfo,
    BottomUp,
    HighEntropy,
    DisableWin32kSystemCalls,
    Audit,
    DisableFsctlSystemCalls,
    AuditFsctlSystemCalls,
    DisableExtensionPoints,
    BlockDynamicCode,
    AllowThreadsToOptOut,
    SuppressExports,
    StrictControlFlowGuard,
    MicrosoftSignedOnly,
    AllowStoreSignedBinaries,
    EnforceModuleDependencySigning,
    AuditStoreSigned,
    AuditEnforceModuleDependencySigning,
    DisableNonSystemFonts,
    BlockRemoteImageLoads,
    BlockLowLabelImageLoads,
    PreferSystem32,
    AuditRemoteImageLoads,
    AuditLowLabelImageLoads,
    AuditPreferSystem32,
    EnableExportAddressFilter,
    AuditEnableExportAddressFilter,
    EnableExportAddressFilterPlus,
    AuditEnableExportAddressFilterPlus,
    EnableImportAddressFilter,
    AuditEnableImportAddressFilter,
    EnableRopStackPivot,
    AuditEnableRopStackPivot,
    EnableRopCallerCheck,
    AuditEnableRopCallerCheck,
    EnableRopSimExec,
    AuditEnableRopSimExec,
    TelemetryOnly,
    TerminateOnError,
    DisallowChildProcessCreation,
    AuditChildProcess,
    UserShadowStack,
    UserShadowStackStrictMode,
    AuditUserShadowStack,
    SetContextIpValidation,
    AuditSetContextIpValidation,
    BlockNonCetBinaries,
    BlockNonCetBinariesNonEhcont,
    AuditBlockNonCetBinaries,
}

impl MitigationOptions {
    pub fn to_parameter_name(self) -> &'static str {
        match self {
            MitigationOptions::DEP => "DEP",
            MitigationOptions::EmulateAtlThunks => "EmulateAtlThunks",
            MitigationOptions::ForceRelocateImages => "ForceRelocateImages",
            MitigationOptions::RequireInfo => "RequireInfo",
            MitigationOptions::BottomUp => "BottomUp",
            MitigationOptions::HighEntropy => "HighEntropy",
            MitigationOptions::StrictHandle => "StrictHandle",
            MitigationOptions::DisableWin32kSystemCalls => "DisableWin32kSystemCalls",
            MitigationOptions::AuditSystemCall => "AuditSystemCall",
            MitigationOptions::DisableExtensionPoints => "DisableExtensionPoints",
            MitigationOptions::DisableFsctlSystemCalls => "DisableFsctlSystemCalls",
            MitigationOptions::AuditFsctlSystemCall => "AuditFsctlSystemCall",
            MitigationOptions::BlockDynamicCode => "BlockDynamicCode",
            MitigationOptions::AllowThreadsToOptOut => "AllowThreadsToOptOut",
            MitigationOptions::AuditDynamicCode => "AuditDynamicCode",
            MitigationOptions::CFG => "CFG",
            MitigationOptions::SuppressExports => "SuppressExports",
            MitigationOptions::StrictCFG => "StrictCFG",
            MitigationOptions::MicrosoftSignedOnly => "MicrosoftSignedOnly",
            MitigationOptions::AllowStoreSignedBinaries => "AllowStoreSignedBinaries",
            MitigationOptions::AuditMicrosoftSigned => "AuditMicrosoftSigned",
            MitigationOptions::AuditStoreSigned => "AuditStoreSigned",
            MitigationOptions::EnforceModuleDependencySigning => "EnforceModuleDependencySigning",
            MitigationOptions::DisableNonSystemFonts => "DisableNonSystemFonts",
            MitigationOptions::AuditFont => "AuditFont",
            MitigationOptions::BlockRemoteImageLoads => "BlockRemoteImageLoads",
            MitigationOptions::BlockLowLabelImageLoads => "BlockLowLabelImageLoads",
            MitigationOptions::PreferSystem32 => "PreferSystem32",
            MitigationOptions::AuditRemoteImageLoads => "AuditRemoteImageLoads",
            MitigationOptions::AuditLowLabelImageLoads => "AuditLowLabelImageLoads",
            MitigationOptions::AuditPreferSystem32 => "AuditPreferSystem32",
            MitigationOptions::EnableExportAddressFilter => "EnableExportAddressFilter",
            MitigationOptions::AuditEnableExportAddressFilter => "AuditEnableExportAddressFilter",
            MitigationOptions::EnableExportAddressFilterPlus => "EnableExportAddressFilterPlus",
            MitigationOptions::AuditEnableExportAddressFilterPlus => {
                "AuditEnableExportAddressFilterPlus"
            }
            MitigationOptions::EnableImportAddressFilter => "EnableImportAddressFilter",
            MitigationOptions::AuditEnableImportAddressFilter => "AuditEnableImportAddressFilter",
            MitigationOptions::EnableRopStackPivot => "EnableRopStackPivot",
            MitigationOptions::AuditEnableRopStackPivot => "AuditEnableRopStackPivot",
            MitigationOptions::EnableRopCallerCheck => "EnableRopCallerCheck",
            MitigationOptions::AuditEnableRopCallerCheck => "AuditEnableRopCallerCheck",
            MitigationOptions::EnableRopSimExec => "EnableRopSimExec",
            MitigationOptions::AuditEnableRopSimExec => "AuditEnableRopSimExec",
            MitigationOptions::SEHOP => "SEHOP",
            MitigationOptions::AuditSEHOP => "AuditSEHOP",
            MitigationOptions::SEHOPTelemetry => "SEHOPTelemetry",
            MitigationOptions::TerminateOnError => "TerminateOnError",
            MitigationOptions::DisallowChildProcessCreation => "DisallowChildProcessCreation",
            MitigationOptions::AuditChildProcess => "AuditChildProcess",
            MitigationOptions::UserShadowStack => "UserShadowStack",
            MitigationOptions::UserShadowStackStrictMode => "UserShadowStackStrictMode",
            MitigationOptions::AuditUserShadowStack => "AuditUserShadowStack",
        }
    }

    pub fn from_parameter_name(parameter_name: &str) -> Result<Self, String> {
        match parameter_name {
            "DEP" => Ok(MitigationOptions::DEP),
            "EmulateAtlThunks" => Ok(MitigationOptions::EmulateAtlThunks),
            "ForceRelocateImages" => Ok(MitigationOptions::ForceRelocateImages),
            "RequireInfo" => Ok(MitigationOptions::RequireInfo),
            "BottomUp" => Ok(MitigationOptions::BottomUp),
            "HighEntropy" => Ok(MitigationOptions::HighEntropy),
            "StrictHandle" => Ok(MitigationOptions::StrictHandle),
            "DisableWin32kSystemCalls" => Ok(MitigationOptions::DisableWin32kSystemCalls),
            "AuditSystemCall" => Ok(MitigationOptions::AuditSystemCall),
            "DisableExtensionPoints" => Ok(MitigationOptions::DisableExtensionPoints),
            "DisableFsctlSystemCalls" => Ok(MitigationOptions::DisableFsctlSystemCalls),
            "AuditFsctlSystemCall" => Ok(MitigationOptions::AuditFsctlSystemCall),
            "BlockDynamicCode" => Ok(MitigationOptions::BlockDynamicCode),
            "AllowThreadsToOptOut" => Ok(MitigationOptions::AllowThreadsToOptOut),
            "AuditDynamicCode" => Ok(MitigationOptions::AuditDynamicCode),
            "CFG" => Ok(MitigationOptions::CFG),
            "SuppressExports" => Ok(MitigationOptions::SuppressExports),
            "StrictCFG" => Ok(MitigationOptions::StrictCFG),
            "MicrosoftSignedOnly" => Ok(MitigationOptions::MicrosoftSignedOnly),
            "AllowStoreSignedBinaries" => Ok(MitigationOptions::AllowStoreSignedBinaries),
            "AuditMicrosoftSigned" => Ok(MitigationOptions::AuditMicrosoftSigned),
            "AuditStoreSigned" => Ok(MitigationOptions::AuditStoreSigned),
            "EnforceModuleDependencySigning" => {
                Ok(MitigationOptions::EnforceModuleDependencySigning)
            }
            "DisableNonSystemFonts" => Ok(MitigationOptions::DisableNonSystemFonts),
            "AuditFont" => Ok(MitigationOptions::AuditFont),
            "BlockRemoteImageLoads" => Ok(MitigationOptions::BlockRemoteImageLoads),
            "BlockLowLabelImageLoads" => Ok(MitigationOptions::BlockLowLabelImageLoads),
            "PreferSystem32" => Ok(MitigationOptions::PreferSystem32),
            "AuditRemoteImageLoads" => Ok(MitigationOptions::AuditRemoteImageLoads),
            "AuditLowLabelImageLoads" => Ok(MitigationOptions::AuditLowLabelImageLoads),
            "AuditPreferSystem32" => Ok(MitigationOptions::AuditPreferSystem32),
            "EnableExportAddressFilter" => Ok(MitigationOptions::EnableExportAddressFilter),
            "AuditEnableExportAddressFilter" => {
                Ok(MitigationOptions::AuditEnableExportAddressFilter)
            }
            "EnableExportAddressFilterPlus" => Ok(MitigationOptions::EnableExportAddressFilterPlus),
            "AuditEnableExportAddressFilterPlus" => {
                Ok(MitigationOptions::AuditEnableExportAddressFilterPlus)
            }
            "EnableImportAddressFilter" => Ok(MitigationOptions::EnableImportAddressFilter),
            "AuditEnableImportAddressFilter" => {
                Ok(MitigationOptions::AuditEnableImportAddressFilter)
            }
            "EnableRopStackPivot" => Ok(MitigationOptions::EnableRopStackPivot),
            "AuditEnableRopStackPivot" => Ok(MitigationOptions::AuditEnableRopStackPivot),
            "EnableRopCallerCheck" => Ok(MitigationOptions::EnableRopCallerCheck),
            "AuditEnableRopCallerCheck" => Ok(MitigationOptions::AuditEnableRopCallerCheck),
            "EnableRopSimExec" => Ok(MitigationOptions::EnableRopSimExec),
            "AuditEnableRopSimExec" => Ok(MitigationOptions::AuditEnableRopSimExec),
            "SEHOP" => Ok(MitigationOptions::SEHOP),
            "AuditSEHOP" => Ok(MitigationOptions::AuditSEHOP),
            "SEHOPTelemetry" => Ok(MitigationOptions::SEHOPTelemetry),
            "TerminateOnError" => Ok(MitigationOptions::TerminateOnError),
            "DisallowChildProcessCreation" => Ok(MitigationOptions::DisallowChildProcessCreation),
            "AuditChildProcess" => Ok(MitigationOptions::AuditChildProcess),
            "UserShadowStack" => Ok(MitigationOptions::UserShadowStack),
            "UserShadowStackStrictMode" => Ok(MitigationOptions::UserShadowStackStrictMode),
            "AuditUserShadowStack" => Ok(MitigationOptions::AuditUserShadowStack),
            _ => Err(format!(
                "Invalid mitigation parameter name: {}",
                parameter_name
            )),
        }
    }

    pub fn get_all_mitigation_options() -> Vec<Self> {
        vec![
            MitigationOptions::DEP,
            MitigationOptions::EmulateAtlThunks,
            MitigationOptions::ForceRelocateImages,
            MitigationOptions::RequireInfo,
            MitigationOptions::BottomUp,
            MitigationOptions::HighEntropy,
            MitigationOptions::StrictHandle,
            MitigationOptions::DisableWin32kSystemCalls,
            MitigationOptions::AuditSystemCall,
            MitigationOptions::DisableExtensionPoints,
            MitigationOptions::DisableFsctlSystemCalls,
            MitigationOptions::AuditFsctlSystemCall,
            MitigationOptions::BlockDynamicCode,
            MitigationOptions::AllowThreadsToOptOut,
            MitigationOptions::AuditDynamicCode,
            MitigationOptions::CFG,
            MitigationOptions::SuppressExports,
            MitigationOptions::StrictCFG,
            MitigationOptions::MicrosoftSignedOnly,
            MitigationOptions::AllowStoreSignedBinaries,
            MitigationOptions::AuditMicrosoftSigned,
            MitigationOptions::AuditStoreSigned,
            MitigationOptions::EnforceModuleDependencySigning,
            MitigationOptions::DisableNonSystemFonts,
            MitigationOptions::AuditFont,
            MitigationOptions::BlockRemoteImageLoads,
            MitigationOptions::BlockLowLabelImageLoads,
            MitigationOptions::PreferSystem32,
            MitigationOptions::AuditRemoteImageLoads,
            MitigationOptions::AuditLowLabelImageLoads,
            MitigationOptions::AuditPreferSystem32,
            MitigationOptions::EnableExportAddressFilter,
            MitigationOptions::AuditEnableExportAddressFilter,
            MitigationOptions::EnableExportAddressFilterPlus,
            MitigationOptions::AuditEnableExportAddressFilterPlus,
            MitigationOptions::EnableImportAddressFilter,
            MitigationOptions::AuditEnableImportAddressFilter,
            MitigationOptions::EnableRopStackPivot,
            MitigationOptions::AuditEnableRopStackPivot,
            MitigationOptions::EnableRopCallerCheck,
            MitigationOptions::AuditEnableRopCallerCheck,
            MitigationOptions::EnableRopSimExec,
            MitigationOptions::AuditEnableRopSimExec,
            MitigationOptions::SEHOP,
            MitigationOptions::AuditSEHOP,
            MitigationOptions::SEHOPTelemetry,
            MitigationOptions::TerminateOnError,
            MitigationOptions::DisallowChildProcessCreation,
            MitigationOptions::AuditChildProcess,
            MitigationOptions::UserShadowStack,
            MitigationOptions::UserShadowStackStrictMode,
            MitigationOptions::AuditUserShadowStack,
        ]
    }
}

impl PolicyName {
    pub fn to_string_value(self) -> &'static str {
        match self {
            PolicyName::DEP => "DEP",
            PolicyName::ASLR => "ASLR",
            PolicyName::StrictHandle => "StrictHandle",
            PolicyName::SystemCalls => "SystemCalls",
            PolicyName::ExtensionPoints => "ExtensionPoints",
            PolicyName::DynamicCode => "DynamicCode",
            PolicyName::ControlFlowGuard => "ControlFlowGuard",
            PolicyName::SignedBinaries => "SignedBinaries",
            PolicyName::Fonts => "Fonts",
            PolicyName::ImageLoad => "ImageLoad",
            PolicyName::Payload => "Payload",
            PolicyName::ChildProcess => "ChildProcess",
            PolicyName::UserShadowStack => "UserShadowStack",
            PolicyName::SEHOP => "SEHOP",
            PolicyName::Heap => "Heap",
        }
    }

    pub fn from_string_value(value: &str) -> Result<Self, String> {
        match value {
            "DEP" => Ok(PolicyName::DEP),
            "ASLR" => Ok(PolicyName::ASLR),
            "StrictHandle" => Ok(PolicyName::StrictHandle),
            "SystemCalls" => Ok(PolicyName::SystemCalls),
            "ExtensionPoints" => Ok(PolicyName::ExtensionPoints),
            "DynamicCode" => Ok(PolicyName::DynamicCode),
            "ControlFlowGuard" => Ok(PolicyName::ControlFlowGuard),
            "SignedBinaries" => Ok(PolicyName::SignedBinaries),
            "Fonts" => Ok(PolicyName::Fonts),
            "ImageLoad" => Ok(PolicyName::ImageLoad),
            "Payload" => Ok(PolicyName::Payload),
            "ChildProcess" => Ok(PolicyName::ChildProcess),
            "UserShadowStack" => Ok(PolicyName::UserShadowStack),
            "SEHOP" => Ok(PolicyName::SEHOP),
            "Heap" => Ok(PolicyName::Heap),
            _ => Err(format!("Unknown policy name string: {}", value)),
        }
    }
}

#[allow(dead_code)]
impl ForceName {
    pub fn to_string_value(self) -> &'static str {
        match self {
            ForceName::DEP => "DEP",
            ForceName::FontDisable => "FontDisable",
            ForceName::ExtensionPoint => "ExtensionPoint",
            ForceName::Heap => "Heap",
            ForceName::BlockRemoteImageLoads => "BlockRemoteImageLoads",
            ForceName::BlockLowLabel => "BlockLowLabel",
            ForceName::PreferSystem32 => "PreferSystem32",
            ForceName::EnableExportAddressFilter => "EnableExportAddressFilter",
            ForceName::EnableExportAddressFilterPlus => "EnableExportAddressFilterPlus",
            ForceName::EnableImportAddressFilter => "EnableImportAddressFilter",
            ForceName::EnableRopStackPivot => "EnableRopStackPivot",
            ForceName::EnableRopCallerCheck => "EnableRopCallerCheck",
            ForceName::EnableRopSimExec => "EnableRopSimExec",
            ForceName::ForceRelocateImages => "ForceRelocateImages",
            ForceName::BottomUp => "BottomUp",
            ForceName::HighEntropy => "HighEntropy",
            ForceName::CFG => "CFG",
            ForceName::StrictCFG => "StrictCFG",
            ForceName::ChildProcess => "ChildProcess",
            ForceName::DynamicCode => "DynamicCode",
            ForceName::StrictHandle => "StrictHandle",
            ForceName::SystemCall => "SystemCall",
            ForceName::DisableFsctlSystem => "DisableFsctlSystem",
            ForceName::UserShadowStack => "UserShadowStack",
            ForceName::SEHOP => "SEHOP",
            ForceName::MicrosoftSignedOnly => "MicrosoftSignedOnly",
            ForceName::EnforceModuleDependencySigning => "EnforceModuleDependencySigning",
        }
    }
}

impl PolicyOptionName {
    pub fn to_string_value(self) -> &'static str {
        match self {
            PolicyOptionName::Enable => "Enable",
            PolicyOptionName::EmulateAtlThunks => "EmulateAtlThunks",
            PolicyOptionName::ForceRelocateImages => "ForceRelocateImages",
            PolicyOptionName::RequireInfo => "RequireInfo",
            PolicyOptionName::BottomUp => "BottomUp",
            PolicyOptionName::HighEntropy => "HighEntropy",
            PolicyOptionName::DisableWin32kSystemCalls => "DisableWin32kSystemCalls",
            PolicyOptionName::Audit => "Audit",
            PolicyOptionName::DisableFsctlSystemCalls => "DisableFsctlSystemCalls",
            PolicyOptionName::AuditFsctlSystemCalls => "AuditFsctlSystemCalls",
            PolicyOptionName::DisableExtensionPoints => "DisableExtensionPoints",
            PolicyOptionName::BlockDynamicCode => "BlockDynamicCode",
            PolicyOptionName::AllowThreadsToOptOut => "AllowThreadsToOptOut",
            PolicyOptionName::SuppressExports => "SuppressExports",
            PolicyOptionName::StrictControlFlowGuard => "StrictControlFlowGuard",
            PolicyOptionName::MicrosoftSignedOnly => "MicrosoftSignedOnly",
            PolicyOptionName::AllowStoreSignedBinaries => "AllowStoreSignedBinaries",
            PolicyOptionName::EnforceModuleDependencySigning => "EnforceModuleDependencySigning",
            PolicyOptionName::AuditStoreSigned => "AuditStoreSigned",
            PolicyOptionName::AuditEnforceModuleDependencySigning => {
                "AuditEnforceModuleDependencySigning"
            }
            PolicyOptionName::DisableNonSystemFonts => "DisableNonSystemFonts",
            PolicyOptionName::BlockRemoteImageLoads => "BlockRemoteImageLoads",
            PolicyOptionName::BlockLowLabelImageLoads => "BlockLowLabelImageLoads",
            PolicyOptionName::PreferSystem32 => "PreferSystem32",
            PolicyOptionName::AuditRemoteImageLoads => "AuditRemoteImageLoads",
            PolicyOptionName::AuditLowLabelImageLoads => "AuditLowLabelImageLoads",
            PolicyOptionName::AuditPreferSystem32 => "AuditPreferSystem32",
            PolicyOptionName::EnableExportAddressFilter => "EnableExportAddressFilter",
            PolicyOptionName::AuditEnableExportAddressFilter => "AuditEnableExportAddressFilter",
            PolicyOptionName::EnableExportAddressFilterPlus => "EnableExportAddressFilterPlus",
            PolicyOptionName::AuditEnableExportAddressFilterPlus => {
                "AuditEnableExportAddressFilterPlus"
            }
            PolicyOptionName::EnableImportAddressFilter => "EnableImportAddressFilter",
            PolicyOptionName::AuditEnableImportAddressFilter => "AuditEnableImportAddressFilter",
            PolicyOptionName::EnableRopStackPivot => "EnableRopStackPivot",
            PolicyOptionName::AuditEnableRopStackPivot => "AuditEnableRopStackPivot",
            PolicyOptionName::EnableRopCallerCheck => "EnableRopCallerCheck",
            PolicyOptionName::AuditEnableRopCallerCheck => "AuditEnableRopCallerCheck",
            PolicyOptionName::EnableRopSimExec => "EnableRopSimExec",
            PolicyOptionName::AuditEnableRopSimExec => "AuditEnableRopSimExec",
            PolicyOptionName::TelemetryOnly => "TelemetryOnly",
            PolicyOptionName::TerminateOnError => "TerminateOnError",
            PolicyOptionName::DisallowChildProcessCreation => "DisallowChildProcessCreation",
            PolicyOptionName::AuditChildProcess => "AuditChildProcess",
            PolicyOptionName::UserShadowStack => "UserShadowStack",
            PolicyOptionName::UserShadowStackStrictMode => "UserShadowStackStrictMode",
            PolicyOptionName::AuditUserShadowStack => "AuditUserShadowStack",
            PolicyOptionName::SetContextIpValidation => "SetContextIpValidation",
            PolicyOptionName::AuditSetContextIpValidation => "AuditSetContextIpValidation",
            PolicyOptionName::BlockNonCetBinaries => "BlockNonCetBinaries",
            PolicyOptionName::BlockNonCetBinariesNonEhcont => "BlockNonCetBinariesNonEhcont",
            PolicyOptionName::AuditBlockNonCetBinaries => "AuditBlockNonCetBinaries",
        }
    }
}

impl MitigationOptions {
    pub fn from_number(number: u32) -> Result<Self, String> {
        match number {
            0 => Ok(MitigationOptions::DEP),
            1 => Ok(MitigationOptions::EmulateAtlThunks),
            2 => Ok(MitigationOptions::ForceRelocateImages),
            3 => Ok(MitigationOptions::RequireInfo),
            4 => Ok(MitigationOptions::BottomUp),
            5 => Ok(MitigationOptions::HighEntropy),
            6 => Ok(MitigationOptions::StrictHandle),
            7 => Ok(MitigationOptions::DisableWin32kSystemCalls),
            8 => Ok(MitigationOptions::AuditSystemCall),
            9 => Ok(MitigationOptions::DisableExtensionPoints),
            10 => Ok(MitigationOptions::DisableFsctlSystemCalls),
            11 => Ok(MitigationOptions::AuditFsctlSystemCall),
            12 => Ok(MitigationOptions::BlockDynamicCode),
            13 => Ok(MitigationOptions::AllowThreadsToOptOut),
            14 => Ok(MitigationOptions::AuditDynamicCode),
            15 => Ok(MitigationOptions::CFG),
            16 => Ok(MitigationOptions::SuppressExports),
            17 => Ok(MitigationOptions::StrictCFG),
            18 => Ok(MitigationOptions::MicrosoftSignedOnly),
            19 => Ok(MitigationOptions::AllowStoreSignedBinaries),
            20 => Ok(MitigationOptions::AuditMicrosoftSigned),
            21 => Ok(MitigationOptions::AuditStoreSigned),
            22 => Ok(MitigationOptions::EnforceModuleDependencySigning),
            23 => Ok(MitigationOptions::DisableNonSystemFonts),
            24 => Ok(MitigationOptions::AuditFont),
            25 => Ok(MitigationOptions::BlockRemoteImageLoads),
            26 => Ok(MitigationOptions::BlockLowLabelImageLoads),
            27 => Ok(MitigationOptions::PreferSystem32),
            28 => Ok(MitigationOptions::AuditRemoteImageLoads),
            29 => Ok(MitigationOptions::AuditLowLabelImageLoads),
            30 => Ok(MitigationOptions::AuditPreferSystem32),
            31 => Ok(MitigationOptions::EnableExportAddressFilter),
            32 => Ok(MitigationOptions::AuditEnableExportAddressFilter),
            33 => Ok(MitigationOptions::EnableExportAddressFilterPlus),
            34 => Ok(MitigationOptions::AuditEnableExportAddressFilterPlus),
            35 => Ok(MitigationOptions::EnableImportAddressFilter),
            36 => Ok(MitigationOptions::AuditEnableImportAddressFilter),
            37 => Ok(MitigationOptions::EnableRopStackPivot),
            38 => Ok(MitigationOptions::AuditEnableRopStackPivot),
            39 => Ok(MitigationOptions::EnableRopCallerCheck),
            40 => Ok(MitigationOptions::AuditEnableRopCallerCheck),
            41 => Ok(MitigationOptions::EnableRopSimExec),
            42 => Ok(MitigationOptions::AuditEnableRopSimExec),
            43 => Ok(MitigationOptions::SEHOP),
            44 => Ok(MitigationOptions::AuditSEHOP),
            45 => Ok(MitigationOptions::SEHOPTelemetry),
            46 => Ok(MitigationOptions::TerminateOnError),
            47 => Ok(MitigationOptions::DisallowChildProcessCreation),
            48 => Ok(MitigationOptions::AuditChildProcess),
            49 => Ok(MitigationOptions::UserShadowStack),
            50 => Ok(MitigationOptions::UserShadowStackStrictMode),
            51 => Ok(MitigationOptions::AuditUserShadowStack),
            _ => Err(format!("Invalid mitigation option number: {}", number)),
        }
    }

    pub fn to_number(self) -> u32 {
        self as u32
    }
}
